// 这个文件的功能：对路由权限进行拦截/管理
import router from './router'
import { asyncRoutes } from './router'
// 进度条模块
import nprogress from 'nprogress'
import 'nprogress/nprogress.css'
// 引入 store
import store from './store'

// 定义白名单：不需要登录（token）就可以直接访问的页面
const whiteList = [
  '/login',
  '/404'
]

// 前置路由守卫
// 执行时机：进入到路由页面之前
// to: 去哪里
// from: 从哪里来
// next: 放行，如果要放行，必须要调用 next()

// 小需求: 尝试使用另一中逻辑完成路由权限的设计
// 白名单中的页面，不判断token，直接放行（login ==> 首页）
// 非白名单页面：必须要判断token，如果没有 ==> 引导到登录页
router.beforeEach(async(to, from, next) => {
  // 打开进度条
  nprogress.start()
  // 如何判断用户去哪里？
  // 如果判断用户有没有登录：有没有 token
  if (store.getters.token) {
    // 已登录

    // 获取用户资料的时机：用户登录以后，进入后台业务页面之前
    // 什么是用户登陆以后：就是能拿到 token
    // 什么是进入业务页面之前： next 放行调用之前
    // 在这里获取用资料
    // 如果用户资料之前已经获取过了，不需要重新获取了
    // 怎么判断用户资料是否已经获取过？？
    if (!store.getters.userId) {
      // 请求接口，获取用户资料：dispatch getUserInfo action
      await store.dispatch('user/getUserInfo')
      // 处理动态路由的注册
      // 处理原则是什么：如果动态路由 在 menus 数组中包含，就注册，否则不注册
      // 需要知道：动态路由的数据  menus 的数据
      // 如何动态注册路由 ： router.addRoutes(路由对象组成的数组)
      // 怎么找：从动态路由表中一个个比对，看这个路由在 menus 中是否存在，如果存在，就注册（记下来），和其他要注册的路由一起组成数组
      // asyncRoutes 要进行遍历 ==> 还是有一个数组
      // asyncRoutes.方法 ==> 数组 map filter
      // map不行：返回的数组的长度和原数组一样长
      // 所以选 filter

      const menus = store.state.user.userinfo.roles.menus
      const regRoutes = asyncRoutes.filter(item => {
        // 如果 menus 中有 就留下 ==> return true 否则不留（return false）
        return menus.includes(item.name)
      })

      store.commit('user/setRoutes', regRoutes)

      // 一定要确保 通配符 兜底的 404 在最后
      router.addRoutes([...regRoutes, { path: '*', redirect: '/404', hidden: true }])
      // asyncRoutes
      // console.log(store.state.user.userinfo)
      next(to.path)
      return
    }

    // to 是一个对象，to.path 才是字符串
    if (to.path === '/login') {
      // 已经登录的情况下，再次登录：直接跳转到 后台首页，避免重复登录
      next('/')
      // 关闭进度条
      nprogress.done()
    } else {
      // 说明已经登录了，访问的是正常的后台页面: 放行
      next()
    }
  } else {
    // 没有登录
    // 如果访问的是 login 404 直接放行
    // if (whiteList.indexOf(to.path) < 0) {
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next('/login')
      nprogress.done()
    }
    // 否则引导到login页面去登录
  }
})

// 后置路由守卫
// 执行时机：进入路由页面之后
router.afterEach(() => {
  // 关闭进度条
  nprogress.done()
})
